package cn.levi.sensitive.configuration;


import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.levi.sensitive.annotations.Sensitive;
import cn.levi.sensitive.component.ActionIfHasSensitiveWord;
import cn.levi.sensitive.component.ActionReplaceSensitiveWord;
import cn.levi.sensitive.component.SensitiveFactory;
import cn.levi.sensitive.component.SensitiveHandler;
import cn.levi.sensitive.enums.SensitiveStrategy;
import cn.levi.sensitive.exceptions.SensitiveException;
import com.fasterxml.jackson.core.JacksonException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Parameter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * 文件路径反序列化时去掉前缀和鉴权参数
 *
 * @author lei
 * @since 2024/9/13
 */
public class SensitiveDeserialize extends JsonDeserializer<String> implements ContextualDeserializer {

	private Sensitive sensitive;


	public SensitiveDeserialize( ) {}
	public SensitiveDeserialize(Sensitive sensitive) {
		this.sensitive = sensitive;
	}

	@Override
	public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JacksonException {
		SensitiveProperties sensitiveProperties = SpringUtil.getBean(SensitiveProperties.class);
		SensitiveFactory sensitiveFactory = SpringUtil.getBean(SensitiveFactory.class);
		String text = p.getText();
		//是否开启，由三方自定义实现，
		if (!sensitiveFactory.isEnable()) {
			return text;
		}
		if (StrUtil.isBlank(text)) {
			return text;
		}
		SensitiveHandler sensitiveHandler = SpringUtil.getBean(SensitiveHandler.class);
		if (sensitiveHandler == null) {
			throw new RuntimeException("未找到SensitiveHandler实例");
		}
		//是否包含敏感词
		if (!sensitiveHandler.isSensitive(text)) {
			return text;
		}
		List<String> allSensitive = sensitiveHandler.matchAllSensitive(text);
		//抛出指定异常
		if (SensitiveStrategy.THROW_EXCEPTION.equals(sensitiveProperties.getStrategy())) {
			throw  new SensitiveException(StrUtil.format(sensitive.value(), CollectionUtil.join(allSensitive,StrUtil.COMMA)));
		}
		//自定义操作，默认采用替换敏感词的操作，如果要自定义操作的话，则实现 ActionIfHasSensitiveWord 接口并加入springboot即可
		ActionIfHasSensitiveWord actionIfHasSensitiveWord = SpringUtil.getBean(ActionIfHasSensitiveWord.class);
		return actionIfHasSensitiveWord.doAction(text);
	}


	@Override
	public JsonDeserializer<?> createContextual(DeserializationContext ctxt, BeanProperty property) throws JsonMappingException {
		if (!Objects.equals(property.getType().getRawClass(), String.class)) {
			return ctxt.findContextualValueDeserializer(property.getType(),property);
		}
		Sensitive sensitiveTarget = property.getAnnotation(Sensitive.class);
		if (sensitiveTarget == null) {
			return ctxt.findContextualValueDeserializer(property.getType(),property);
		}
		return new SensitiveDeserialize(sensitiveTarget);
	}
}
